import { Application } from 'egg';
import crypto = require('crypto');
import { UserInfoEntity, EUserPwdStrength } from '../model/user';

export default {
  /**
   * 加密
   * @param this application实例
   * @param secretKey 密钥
   * @param password 需要加密的文体
   */
  cryptoTextByHmac(this: Application, secretKey: string, text: string) {
    const hmac = crypto.createHmac('sha256', secretKey);
    hmac.update(text);
    const cryptoPwd = hmac.digest('hex');
    return cryptoPwd;
  },
  /**
   * 创建Mongoose插入数据的对象
   * @param insertParamsObj 要插入数据库的参数
   * @param dealObj 需要处理的对象，{key: object | () => object}
   * key为insertParamsObj中需要特殊处理的key值
   * key对应的object或函数所返回的object将合并到最终的结果对象一起返回
   */
  generateInsertObj(insertParamsObj: object, dealObj?: object) {
    let insertObj = {};
    Object.keys(insertParamsObj).forEach(key => {
      if (insertParamsObj[key] !== undefined) {
        if (dealObj && dealObj[key]) {
          let dealKeyVal = {};
          if (typeof dealObj[key] === 'function') {
            dealKeyVal = dealObj[key]();
          } else if (
            Object.prototype.toString.call(dealObj[key]) === '[object Object]'
          ) {
            dealKeyVal = dealObj[key];
          }
          insertObj = {
            ...insertObj,
            ...dealKeyVal,
          };
        } else {
          insertObj[key] = insertParamsObj[key];
        }
      }
    });
    return insertObj;
  },
  /**
   * 根据token来获取用户信息
   * @param bearerStr token字符串
   */
  getUserInfoByToken(bearerStr: string, app: Application) {
    const authToken = bearerStr.split(' ')[1] || '';
    const curUserInfo = ((app.jwt.decode(authToken) as unknown) as {
      userInfo: UserInfoEntity;
    }).userInfo;
    return curUserInfo;
  },
  /**
   * 判断密码强度
   * @param password 判断强度的密码
   */
  judgePwdStrength(password: string) {
      let pwdStrength = EUserPwdStrength.UNSAFE;
      // 强密码
      const strongRegex = new RegExp('^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$', 'g');
      // 良好密码
      const enoughRegex = new RegExp('^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$', 'g');
      // 弱密码
      const weekRegex = new RegExp('(?=.{6,}).*', 'g');
      if (strongRegex.test(password)) {
        pwdStrength = EUserPwdStrength.STRONG;
      } else if (enoughRegex.test(password)) {
        pwdStrength = EUserPwdStrength.ENOUGH;
      } else if (weekRegex.test(password)) {
        pwdStrength = EUserPwdStrength.WEEK;
      }
      return pwdStrength;
  },
};
